home *** CD-ROM | disk | FTP | other *** search
- *
- * $VER: cosh.s 33.1 (23.1.97)
- *
- * hyperbolic cosine
- *
- * Version history:
- *
- * 33.1 23.1.97 (c) Motorola
- *
- * - snipped from M68060SP sources
- *
-
- machine 68040
- fpu 1
-
- XDEF _cosh
- XDEF @cosh
-
- XREF @exp
-
- *************************************************************************
- * cosh(): computes the hyperbolic cosine of a normalized input *
- * *
- * INPUT *************************************************************** *
- * fp0 = extended precision input *
- * *
- * OUTPUT ************************************************************** *
- * fp0 = cosh(X) *
- * *
- * ACCURACY and MONOTONICITY ******************************************* *
- * The returned result is within 3 ulps in 64 significant bit, *
- * i.e. within 0.5001 ulp to 53 bits if the result is subsequently *
- * rounded to double precision. The result is provably monotonic *
- * in double precision. *
- * *
- * ALGORITHM *********************************************************** *
- * *
- * COSH *
- * 1. If |X| > 16380 log2, go to 3. *
- * *
- * 2. (|X| <= 16380 log2) Cosh(X) is obtained by the formulae *
- * y = |X|, z = exp(Y), and *
- * cosh(X) = (1/2)*( z + 1/z ). *
- * Exit. *
- * *
- * 3. (|X| > 16380 log2). If |X| > 16480 log2, go to 5. *
- * *
- * 4. (16380 log2 < |X| <= 16480 log2) *
- * cosh(X) = sign(X) * exp(|X|)/2. *
- * However, invoking exp(|X|) may cause premature *
- * overflow. Thus, we calculate sinh(X) as follows: *
- * Y := |X| *
- * Fact := 2**(16380) *
- * Y' := Y - 16381 log2 *
- * cosh(X) := Fact * exp(Y'). *
- * Exit. *
- * *
- * 5. (|X| > 16480 log2) sinh(X) must overflow. Return *
- * Huge*Huge to generate overflow and an infinity with *
- * the appropriate sign. Huge is the largest finite number *
- * in extended format. Exit. *
- * *
- *************************************************************************
-
- TWO16380
- dc.l $7FFB0000,$80000000,$00000000,$00000000
- T1 dc.l $40C62D38,$D3D64634 ; 16381 LOG2 LEAD
- T2 dc.l $3D6F90AE,$B1E75CC7 ; 16381 LOG2 TRAIL
-
- _cosh
- fmove.d (4,sp),fp0
- @cosh
- fmove.x fp0,-(sp)
-
- move.l (sp),d1
- move.w (4,sp),d1
- and.l #$7FFFFFFF,d1
- lea (12,sp),sp
- cmp.l #$400CB167,d1
- bgt.b .COSHBIG
-
- ;--THIS IS THE USUAL CASE, |X| < 16380 LOG2
- ;--COSH(X) = (1/2) * ( EXP(X) + 1/EXP(X) )
-
- fabs.x fp0 ; |X|
-
- jsr @exp ; FP0 IS EXP(|X|)
- fmul.s #$3F000000,fp0 ; (1/2)EXP(|X|)
-
- fmove.s #$3E800000,fp1 ; (1/4)
- fdiv.x fp0,fp1 ; 1/(2 EXP(|X|))
-
- fadd.x fp1,fp0
- rts
-
- .COSHBIG
- cmp.l #$400CB2B3,d1
- bgt.b .COSHHUGE
-
- fabs.x fp0
- fsub.d (T1,pc),fp0 ; (|X|-16381LOG2_LEAD)
- fsub.d (T2,pc),fp0 ; |X| - 16381 LOG2, ACCURATE
-
- jsr @exp
- fmul.x (TWO16380,pc),fp0
- .COSHHUGE
- rts
-